﻿namespace Digitalmes.Application.Mes;

/// <summary>
/// 存档数据追溯
/// </summary>
[ApiExplorerSettings(GroupName = "mes")]
public sealed class TraceArchiveService : IDynamicWebApiService
{
    private readonly SugarRepository<ProdArchive> _archiveRepo;

    public TraceArchiveService(SugarRepository<ProdArchive> archiveRepo)
    {
        _archiveRepo = archiveRepo;
    }

    /// <summary>
    /// 动态生成分页
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    [HttpGet]
    public async Task<DynamicPageResult<Dictionary<string, string>>> DynamicPagesAsync(TraceArchivePageParam param)
    {
        DynamicPageResult<Dictionary<string, string>> dto = new()
        {
            Columns =
            [
                new UIElementTableColumn { Prop = nameof(ProdArchive.Id), Label = "Id", Hide = true },
                new UIElementTableColumn { Prop = nameof(ProdArchive.ArchiveTime), Label = "过站时间", Width = "140" },
                new UIElementTableColumn { Prop = nameof(ProdArchive.Sn), Label = "SN", Width = "240" },
                new UIElementTableColumn { Prop = nameof(ProdArchive.LineCode), Label = "产线编号", Width = "160" },
                new UIElementTableColumn { Prop = nameof(ProdArchive.OpCode), Label = "工位编号" },
                new UIElementTableColumn { Prop = nameof(ProdArchive.ProcCode), Label = "工序编号" },
                new UIElementTableColumn { Prop = nameof(ProdArchive.ProductCode), Label = "产品编号", Width = "160" },
                new UIElementTableColumn { Prop = nameof(ProdArchive.PassResult), Label = "过站结果" },
                new UIElementTableColumn { Prop = nameof(ProdArchive.Operator), Label = "操作人" },
                new UIElementTableColumn { Prop = nameof(ProdArchiveData.TypeName), Label = "数据分类", Width = "120" },
            ],
            PageData = new(),
        };

        var query = await _archiveRepo.AsQueryable()
           .LeftJoin<ProdInbound>((a, i) => a.Sn == i.Sn && a.Version == i.Version)
           .LeftJoin<ProdArchiveData>((a, i, d) => a.Id == d.ArchiveId)
           .Where(a => a.LineCode == param.LineCode && a.OpCode == param.OpCode)
           .WhereIF(param.StartTime != null, a => a.ArchiveTime >= param.StartTime.MinTime())
           .WhereIF(param.EndTime != null, a => a.ArchiveTime <= param.EndTime.MaxTime())
           .Select((a, i, d) => new { a, i, d })
           .ToPageAsync(param.Page, param.Limit);

        // 转换为字典对象
        HashSet<string> fields = []; // 过程数据字段
        List<Dictionary<string, string>> items = [];
        foreach (var item in query.Items)
        {
            ProdInbound inbound = item.i;
            ProdArchive archive = item.a;
            ProdArchiveData archiveData = item.d;

            Dictionary<string, string> dict = [];
            items.Add(dict);

            // 主数据
            dict[nameof(ProdArchive.Id)] = archive.Id.ToString();
            dict[nameof(ProdArchive.ArchiveTime)] = archive.ArchiveTime.ToString("yyyy-MM-dd HH:mm:ss");
            dict[nameof(ProdArchive.Sn)] = archive.Sn;
            dict[nameof(ProdArchive.LineCode)] = archive.LineCode;
            dict[nameof(ProdArchive.OpCode)] = archive.OpCode;
            dict[nameof(ProdArchive.ProcCode)] = archive.ProcCode;
            dict[nameof(ProdArchive.ProductCode)] = archive.ProductCode ?? "";
            dict[nameof(ProdArchive.PassResult)] = archive.PassResult.Description();
            dict[nameof(ProdArchive.Operator)] = archive.Operator ?? "";
            dict[nameof(ProdArchiveData.TypeName)] = archiveData.TypeName;

            // 过程数据处理
            foreach (var data in archiveData.Data)
            {
                // 名称格式: 若存在编号，则为 "显示名称-编号"，否则直接为显示名称。
                var name = data.I > 0 ? $"{data.K}-{data.I}" : data.K;
                fields.Add(name);
                dict[name] = data.V;
            }
        }

        if (fields.Count > 0)
        {
            dto.Columns.AddRange(fields.Select(field => new UIElementTableColumn 
            { 
                Prop = field,
                Label = field,
                Width = "120",
            }));
        }

        dto.PageData = new PageResult<Dictionary<string, string>>
        {
            TotalItems = query.TotalItems,
            TotalPages = query.TotalPages,
            Items = items,
        };

        return dto;
    }
}
